--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 15600d5172bb14bb6ab457474f18c0b7a79bd837
Parents : 887c0a9
Author : Mark Qvist <mark@unsigned.io>
Date : 2024-12-11T19:25:46+01:00
Added signal stats to announce stream
Changes
3 files changed, 76 insertions(+), 23 deletions(-)
Diff
diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index e0753fe9..85134c94 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -45,7 +45,7 @@ class PropagationNodeDetector():
aspect_filter = "lxmf.propagation"
- def received_announce(self, destination_hash, announced_identity, app_data):
+ def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
try:
if app_data != None and len(app_data) > 0:
if pn_announce_data_is_valid(app_data):
@@ -64,8 +64,12 @@ class PropagationNodeDetector():
# age = 0
pass
+ link_stats = {"rssi": self.reticulum.get_packet_rssi(announce_packet_hash),
+ "snr": self.reticulum.get_packet_snr(announce_packet_hash),
+ "q": self.reticulum.get_packet_q(announce_packet_hash)}
+
RNS.log("Detected active propagation node "+RNS.prettyhexrep(destination_hash)+" emission "+str(age)+" seconds ago, "+str(hops)+" hops away")
- self.owner.log_announce(destination_hash, app_data, dest_type=PropagationNodeDetector.aspect_filter)
+ self.owner.log_announce(destination_hash, app_data, dest_type=PropagationNodeDetector.aspect_filter, link_stats=link_stats)
if self.owner.config["lxmf_propagation_node"] == None:
if self.owner.active_propagation_node == None:
@@ -114,10 +118,14 @@ class SidebandCore():
LOG_DEQUE_MAXLEN = 128
aspect_filter = "lxmf.delivery"
- def received_announce(self, destination_hash, announced_identity, app_data):
+ def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
# Add the announce to the directory announce
# stream logger
+ link_stats = {"rssi": self.reticulum.get_packet_rssi(announce_packet_hash),
+ "snr": self.reticulum.get_packet_snr(announce_packet_hash),
+ "q": self.reticulum.get_packet_q(announce_packet_hash)}
+
# This reformats the new v0.5.0 announce data back to the expected format
# for Sidebands database and other handling functions.
dn = LXMF.display_name_from_app_data(app_data)
@@ -126,7 +134,7 @@ class SidebandCore():
if dn != None:
app_data = dn.encode("utf-8")
- self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter, stamp_cost=sc)
+ self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter, stamp_cost=sc, link_stats=link_stats)
def __init__(self, owner_app, config_path = None, is_service=False, is_client=False, android_app_dir=None, verbose=False, owner_service=None, service_context=None, is_daemon=False, load_config_only=False):
self.is_service = is_service
@@ -961,14 +969,14 @@ class SidebandCore():
else:
plyer.notification.notify(title, content, app_icon=self.icon_32)
- def log_announce(self, dest, app_data, dest_type, stamp_cost=None):
+ def log_announce(self, dest, app_data, dest_type, stamp_cost=None, link_stats=None):
try:
if app_data == None:
app_data = b""
if type(app_data) != bytes:
app_data = msgpack.packb([app_data, stamp_cost])
RNS.log("Received "+str(dest_type)+" announce for "+RNS.prettyhexrep(dest)+" with data: "+str(app_data), RNS.LOG_DEBUG)
- self._db_save_announce(dest, app_data, dest_type)
+ self._db_save_announce(dest, app_data, dest_type, link_stats)
self.setstate("app.flags.new_announces", True)
except Exception as e:
@@ -1980,10 +1988,10 @@ class SidebandCore():
# TODO: Remove this again at some point in the future
db = self.__db_connect()
dbc = db.cursor()
- dbc.execute("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'lxm' AND sql LIKE '%extra%'")
+ dbc.execute("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'announce' AND sql LIKE '%extra%'")
result = dbc.fetchall()
if len(result) == 0:
- dbc.execute("ALTER TABLE lxm ADD COLUMN extra BLOB")
+ dbc.execute("ALTER TABLE announce ADD COLUMN extra BLOB")
db.commit()
def _db_initstate(self):
@@ -2540,8 +2548,16 @@ class SidebandCore():
for entry in result:
try:
if not entry[2] in added_dests:
- app_data = entry[3]
+ app_data = entry[3]
dest_type = entry[4]
+ if entry[5] != None:
+ try:
+ extras = msgpack.unpackb(entry[5])
+ except Exception as e:
+ RNS.log(f"Error while unpacking extras from announce: {e}", RNS.LOG_ERROR)
+ extras = None
+ else:
+ extras = None
if dest_type == "lxmf.delivery":
announced_name = LXMF.display_name_from_app_data(app_data)
announced_cost = self.message_router.get_outbound_stamp_cost(entry[2])
@@ -2549,11 +2565,12 @@ class SidebandCore():
announced_name = None
announced_cost = None
announce = {
- "dest": entry[2],
- "name": announced_name,
- "cost": announced_cost,
- "time": entry[1],
- "type": dest_type
+ "dest" : entry[2],
+ "name" : announced_name,
+ "cost" : announced_cost,
+ "time" : entry[1],
+ "type" : dest_type,
+ "extras": extras,
}
added_dests.append(entry[2])
announces.append(announce)
@@ -2967,7 +2984,7 @@ class SidebandCore():
self.__event_conversation_changed(context_dest)
- def _db_save_announce(self, destination_hash, app_data, dest_type="lxmf.delivery"):
+ def _db_save_announce(self, destination_hash, app_data, dest_type="lxmf.delivery", link_stats = None):
with self.db_lock:
db = self.__db_connect()
dbc = db.cursor()
@@ -2981,14 +2998,16 @@ class SidebandCore():
now = time.time()
hash_material = str(time).encode("utf-8")+destination_hash+app_data+dest_type.encode("utf-8")
announce_hash = RNS.Identity.full_hash(hash_material)
+ extras = msgpack.packb({"link_stats": link_stats})
- query = "INSERT INTO announce (id, received, source, data, dest_type) values (?, ?, ?, ?, ?)"
+ query = "INSERT INTO announce (id, received, source, data, dest_type, extra) values (?, ?, ?, ?, ?, ?)"
data = (
announce_hash,
now,
destination_hash,
app_data,
dest_type,
+ extras,
)
dbc.execute(query, data)
diff --git a/sbapp/ui/announces.py b/sbapp/ui/announces.py
index 5e58dbb8..be887127 100644
--- a/sbapp/ui/announces.py
+++ b/sbapp/ui/announces.py
@@ -18,9 +18,9 @@ from kivy.lang.builder import Builder
from kivy.utils import escape_markup
if RNS.vendor.platformutils.get_platform() == "android":
- from ui.helpers import multilingual_markup
+ from ui.helpers import multilingual_markup, sig_icon_for_q
else:
- from .helpers import multilingual_markup
+ from .helpers import multilingual_markup, sig_icon_for_q
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format
@@ -92,6 +92,25 @@ class Announces():
a_name = announce["name"]
a_cost = announce["cost"]
dest_type = announce["type"]
+ a_rssi = None
+ a_snr = None
+ a_q = None
+
+ link_extras_str = ""
+ link_extras_full = ""
+ if "extras" in announce and announce["extras"] != None:
+ extras = announce["extras"]
+ RNS.log("Announce has extras: "+str(announce["extras"]))
+ if "link_stats" in extras:
+ link_stats = extras["link_stats"]
+ if "rssi" in link_stats and "snr" in link_stats and "q" in link_stats:
+ a_rssi = link_stats["rssi"]
+ a_snr = link_stats["snr"]
+ a_q = link_stats["q"]
+ link_extras_str = f" ([b]RSSI[/b] {a_rssi} [b]SNR[/b] {a_snr})"
+ link_extras_full = f"\n[b]Link Quality[/b] {a_q}%[/b]\n[b]RSSI[/b] {a_rssi}\n[b]SNR[/b] {a_snr}"
+
+ sig_icon = multilingual_markup(sig_icon_for_q(a_q).encode("utf-8")).decode("utf-8")
if not context_dest in self.added_item_dests:
if self.app.sideband.is_trusted(context_dest):
@@ -99,16 +118,16 @@ class Announces():
else:
trust_icon = "account-question"
- def gen_info(ts, dest, name, cost, dtype):
+ def gen_info(ts, dest, name, cost, dtype, link_extras):
name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8")
cost = str(cost)
def x(sender):
yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
if dtype == "lxmf.delivery":
- ad_text = "[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+"\n[b]Name[/b] "+name+"\n[b]Stamp Cost[/b] "+cost
+ ad_text = "[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+"\n[b]Name[/b] "+name+"\n[b]Stamp Cost[/b] "+cost+link_extras
if dtype == "lxmf.propagation":
- ad_text = "[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)
+ ad_text = "[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+link_extras
dialog = MDDialog(
text=ad_text,
@@ -123,7 +142,8 @@ class Announces():
dialog.open()
return x
- time_string = time.strftime(ts_format, time.localtime(ts))
+ time_string = sig_icon + " " + time.strftime(ts_format, time.localtime(ts)) + link_extras_str
+ time_string_plain = time.strftime(ts_format, time.localtime(ts))
if dest_type == "lxmf.delivery":
disp_name = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(context_dest))).encode("utf-8")).decode("utf-8")
@@ -137,7 +157,7 @@ class Announces():
disp_name = "Unknown Announce"
iconl = IconLeftWidget(icon="progress-question")
- item = TwoLineAvatarIconListItem(text=time_string, secondary_text=disp_name, on_release=gen_info(time_string, context_dest, a_name, a_cost, dest_type))
+ item = TwoLineAvatarIconListItem(text=time_string, secondary_text=disp_name, on_release=gen_info(time_string_plain, context_dest, a_name, a_cost, dest_type, link_extras_full))
item.add_widget(iconl)
item.sb_uid = context_dest
item.ts = ts
diff --git a/sbapp/ui/helpers.py b/sbapp/ui/helpers.py
index c02a2f59..80d2971c 100644
--- a/sbapp/ui/helpers.py
+++ b/sbapp/ui/helpers.py
@@ -111,6 +111,20 @@ def multilingual_markup(data):
return do.encode("utf-8")
+def sig_icon_for_q(q):
+ if q == None:
+ return ""
+ elif q > 90:
+ return ""
+ elif q > 70:
+ return ""
+ elif q > 50:
+ return ""
+ elif q > 30:
+ return ""
+ elif q > 10:
+ return ""
+
persistent_fonts = ["nf", "term"]
nf_mapped = "nf"
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────